package cn.imjzm.runcarserve.service.impl;

import cn.imjzm.runcarserve.mapper.LoginMapper;
import cn.imjzm.runcarserve.mapper.RegistMapper;
import cn.imjzm.runcarserve.pojo.User;
import cn.imjzm.runcarserve.service.RegistService;
import cn.imjzm.runcarserve.utils.EmailService;
import cn.imjzm.runcarserve.utils.Redis;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.Random;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;

@Slf4j
@Service
public class RegistServicelmpl implements RegistService {

    @Autowired
    private LoginMapper loginMapper;

    @Autowired
    private EmailService emailService;

    @Autowired
    private Redis redisTemplate;

    @Autowired
    private RegistMapper registMapper;


    // 发送间隔限制（60秒）
    private static final long SEND_INTERVAL = 60 * 1000;

    @Override
    public void sendEmailVerificationCode(String email) {
        // 检查是否已存在验证码记录
        VerificationCode existingCode = redisTemplate.getValue(email, VerificationCode.class);

        String codeToSend;

        if (existingCode != null && System.currentTimeMillis() < existingCode.getExpireTime()) {
            // 检查发送频率限制
            if (System.currentTimeMillis() - existingCode.getLastSendTime() < SEND_INTERVAL) {
                long remainingTime = (SEND_INTERVAL - (System.currentTimeMillis() - existingCode.getLastSendTime())) / 1000;
                throw new RuntimeException("请求过于频繁，请" + remainingTime + "秒后重试");
            }

            // 重发现有验证码，更新最后发送时间
            codeToSend = existingCode.getCode();
            VerificationCode updatedCode = new VerificationCode(
                    existingCode.getCode(),
                    existingCode.getExpireTime(),
                    System.currentTimeMillis()
            );

            // 计算剩余过期时间
            long remainingTime = (existingCode.getExpireTime() - System.currentTimeMillis()) / 1000;
            redisTemplate.setValue(email, updatedCode, remainingTime);

            log.info("重新发送未过期的验证码 - 邮箱: {}", email);
        } else {
            // 生成新的验证码
            codeToSend = generateVerificationCode();
            long currentTime = System.currentTimeMillis();
            long expireTime = currentTime + 5 * 60 * 1000;

            VerificationCode verificationCode = new VerificationCode(codeToSend, expireTime, currentTime);
            redisTemplate.setValue(email, verificationCode, 5 * 60);

            log.info("生成并存储新的验证码 - 邮箱: {}", email);
        }

        // 发送邮件
        String subject = "【RunCar】邮箱验证码";
        String htmlContent = buildVerificationEmailContent(codeToSend);
        emailService.sendHtmlEmail(email, subject, htmlContent);

        log.info("邮箱验证码发送成功 - 邮箱: {}", email);
    }

    @Override
    public boolean verifyEmailCode(String email, String code) {
        VerificationCode storedCode = redisTemplate.getValue(email, VerificationCode.class);

        if (storedCode == null) {
            log.warn("验证码不存在 - 邮箱: {}", email);
            return false;
        }

        // 检查是否过期
        if (System.currentTimeMillis() > storedCode.getExpireTime()) {
            redisTemplate.delete(email);
            log.warn("验证码已过期 - 邮箱: {}", email);
            return false;
        }

        // 验证码验证
        boolean isValid = storedCode.getCode().equals(code);

        if (isValid) {
            redisTemplate.delete(email);
            log.info("邮箱验证码验证成功 - 邮箱: {}", email);
        } else {
            log.warn("邮箱验证码错误 - 邮箱: {}", email);
        }

        return isValid;
    }

    @Override
    public String RegistUser(User user) {
        // 密码加密
        BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
        String encryptedPassword = encoder.encode(user.getPassword());
        user.setPassword(encryptedPassword);

        // 根据手机号查找用户
        User userFromDb = loginMapper.selectByEmail(user.getEmail());
        if (userFromDb == null) {
            // 发送注册邮件
            emailService.sendRegistrationEmail(user);
            // 将用户信息保存到数据库
            registMapper.insertUser(user);
        }else {
            return "User already using";
        }
            return "success";
    }

    @Override
    public String reset(String email, String code, String password) {

        VerificationCode storedCode = redisTemplate.getValue(email, VerificationCode.class);

        if (storedCode == null) {
            log.warn("验证码不存在 - 邮箱: {}", email);
            return "no1";
        }

        // 检查是否过期
        if (System.currentTimeMillis() > storedCode.getExpireTime()) {
            redisTemplate.delete(email);
            log.warn("验证码已过期 - 邮箱: {}", email);
            return "no1";
        }

        // 验证码验证
        boolean isValid = storedCode.getCode().equals(code);

        if (isValid) {
            redisTemplate.delete(email);
            log.info("邮箱验证码验证成功 - 邮箱: {}", email);
            User userFromDb = loginMapper.selectByEmail(email);
            if (userFromDb != null) {
                registMapper.reset(email,password);

            }else {
                return "noexist";//邮箱不存在
            }

        } else {
            log.warn("邮箱验证码错误 - 邮箱: {}", email);
        }


        return "success";

    }


    /**
     * 生成6位数字验证码
     */
    private String generateVerificationCode() {
        Random random = new Random();
        return String.format("%06d", random.nextInt(1000000));
    }

    /**
     * 构建验证码邮件内容
     */
    private String buildVerificationEmailContent(String code) {
        return "<!DOCTYPE html>" +
                "<html>" +
                "<head><meta charset=\"UTF-8\"><title>邮箱验证</title></head>" +
                "<body style=\"font-family: Arial, sans-serif; line-height: 1.6; color: #333;\">" +
                "<div style=\"max-width: 600px; margin: 0 auto; padding: 20px;\">" +
                "<h2 style=\"color: #2c3e50;\">📧 邮箱验证码</h2>" +
                "<p>您正在注册 RunCar 账户，验证码为：</p>" +
                "<div style=\"background-color: #f8f9fa; padding: 20px; border-radius: 8px; text-align: center; margin: 20px 0;\">" +
                "<span style=\"font-size: 32px; font-weight: bold; color: #007bff; letter-spacing: 8px;\">" + code + "</span>" +
                "</div>" +
                "<p style=\"color: #6c757d;\">验证码有效期为 5 分钟，请及时使用。</p>" +
                "<p style=\"color: #dc3545; font-size: 14px;\">如果这不是您的操作，请忽略此邮件。</p>" +
                "<p style=\"color: #7f8c8d; font-size: 14px;\">此邮件由系统自动发送，请勿回复。</p>" +
                "</div>" +
                "</body>" +
                "</html>";
    }

    /**
     * 验证码存储类
     */
    private static class VerificationCode {
        private final String code;
        private final long expireTime;
        private final long lastSendTime; // 最后发送时间

        public VerificationCode(String code, long expireTime) {
            this(code, expireTime, System.currentTimeMillis());
        }

        public VerificationCode(String code, long expireTime, long lastSendTime) {
            this.code = code;
            this.expireTime = expireTime;
            this.lastSendTime = lastSendTime;
        }

        public String getCode() {
            return code;
        }

        public long getExpireTime() {
            return expireTime;
        }

        public long getLastSendTime() {
            return lastSendTime;
        }
    }
}